/******************************************************************************
 * This file is part of libemb.
 *
 * libemb is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * libemb is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with libemb.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Project: Embedme
 * Author : FergusZeng
 * Email  : cblock@126.com
 * git	  : https://git.oschina.net/cblock/embedme
 * Copyright 2014~2020 @ ShenZhen ,China
*******************************************************************************/
#ifndef __BASE_TYPE_H__
#define __BASE_TYPE_H__

#include <iostream>
#include <vector>

namespace libemb{
/**
 *  \file  BaseType.h
 *  \brief
 */
typedef signed char        sint8;
typedef signed short       sint16;
typedef signed int         sint32;
typedef signed long long   sint64;
typedef unsigned char      uint8;
typedef unsigned short     uint16;
typedef unsigned int       uint32;
typedef unsigned long long uint64;

/** 定义函数返回值 */
typedef enum
{
    STATUS_OK = 0,      /**< 返回值:正常 */
    STATUS_ERROR = -1,  /**< 返回值:出错 */
    STATUS_TIMEOUT = -2,/**< 返回值:超时 */
}STATUS_E;

/** 定义数据类型 */
typedef enum
{
    BASETYPE_NONE=0,        /**< 未知类型 */
    BASETYPE_INT,           /**< 整数 */
    BASETYPE_DOUBLE,        /**< 浮点数 */
    BASETYPE_STRING,        /**< 字符串 */
    BASETYPE_INTARRAY,      /**< 整数数组 */
    BASETYPE_DOUBLEARRAY,   /**< 浮点数数组 */
    BASETYPE_STRINGARRAY,   /**< 字符串数组 */
    BASETYPE_TUPLE,         /**< 元组 */
}BASETYPE_E;
}

/** 计算数组大小(元素个数) \a array.*/
#define ARRAY_SIZE(array)   (sizeof(array)/sizeof(array[0]))    

/** 判断一个字符是否是十进制数字 \a ch.*/
#define IS_DIGITAL(ch)   ((((ch)>='0')&&((ch)<='9'))?true:false)

/** 判断一个字符是否是16进制数字 \a ch.*/
#define IS_HEXDIG(ch)    (((((ch)>='0')&&((ch)<='9'))||(((ch)>='A')&&((ch)<='F'))||(((ch)>='a')&&((ch)<='f')))?true:false)

/** 判断一个字符是否是大写字母 \a ch.*/
#define IS_CAPITAL(ch)   ((((ch)>='A')&&((ch)<='Z'))?true:false)

/** 判断一个字符是否是字母 \a ch.*/
#define IS_ALPHABET(ch)  (((((ch)>='A')&&((ch)<='Z'))||(((ch)>='a')&&((ch)<='b')))?true:false)

/** 返回 \a x 和 \a y 中较大值. */
#define MAX(x,y) (((x)>(y))?(x):(y))

/** 返回 \a x 和 \a y 中较小值. */
#define MIN(x,y) (((x)<(y))?(x):(y))

/** 在 \a min 和 \a max 区间中取与 \a x 大小较接近的数值. */
#define CLIP(min,x,max) (((x)>(max))?(max):(((x)<(min))?(min):(x)))

#define PI              	(3.1415926)     /**< 圆周率. */
#define SQUARE(x)       	((x)*(x))       /**< \a x 的平方. */
#define R_AREA(r)       	((PI)*(r)*(r))  /**< 计算半径为\a r 的圆的面积. */
#define FLOAT_EQU(f1,f2,prec)	(fabs((f1)-(f2))<(prec))	/**<  判断浮点数是否相等 */

#define BIT_GET(value,bit)      (!!((0x0001<<(bit))&(value)))   /**< 获取value的第bit位的值 */
#define BIT_SET(value,bit)      ((0x0001<<(bit))|(value))       /**< 设置value的第bit位的值 */
#define BIT_CLR(value,bit)      ((~(0x0001<<(bit)))&(value))    /**< 清除value的第bit位的值 */


#define NEW_OBJ         new     /** 替代new操作符,便以检查内存泄露,代码中不要再使用new和delete!!! */
#define DEL_OBJ(object) {if((object)!=NULL){delete (object);(object)=NULL;}}/** 替代delete操作符,便以检查内存泄露,必须与NEW_OBJ配对使用!!! */
#define UNUSED_PARAM(param) {(param)==(param);}                 /** 消除未使用变量警告 */
#define ENUM2STRING(enum_symbol)  {enum_symbol,#enum_symbol}    /** 枚举转字符串 */
#define CSTR(stdstr)		((stdstr).c_str())		
#define CH2STR(ch)			(std::string(1,(char)ch))
typedef struct{
    int value;
    const char *name;
}Enum2String_S;

namespace libemb{
/**
 *  \file   BaseType.h   
 *  \class  Array
 *  \brief  抽象数组类	
 */
class Array{
public:
    Array();
    virtual ~Array();
    virtual bool initWithString(const std::string& arrayString)=0;
    int type();
    virtual int size()=0;
    virtual void clear()=0;
    virtual std::string serialize()=0;
protected:
    int m_type;
};

/**
 *  \file   BaseType.h   
 *  \class  IntArray
 *  \brief  整型数组类	
 */
class IntArray:public Array{
public:
    IntArray();
    IntArray(const std::string& arrayString);
    IntArray(const IntArray& copyArray);
    ~IntArray();
    bool initWithString(const std::string& arrayString);
    std::string serialize();
    int size();
    void clear();
    int& operator[](int idx);
    IntArray& operator=(const IntArray&);
    IntArray& append(int item);
private:
    std::vector<int> m_array;
};

/**
 *  \file   BaseType.h   
 *  \class  DoubleArray
 *  \brief  浮点型数组类	
 */
class DoubleArray:public Array{
public:
    DoubleArray();
    DoubleArray(const std::string& arrayString);
    DoubleArray(const DoubleArray& copyArray);
    ~DoubleArray();
    bool initWithString(const std::string& arrayString);
    std::string serialize();
    int size();
    void clear();
    double& operator[](int idx);
    DoubleArray& operator=(const DoubleArray&);
    DoubleArray& append(double item);
private:
    std::vector<double> m_array;
};

/**
 *  \file   BaseType.h   
 *  \class  StringArray
 *  \brief  字符串型数组类	
 */
class StringArray:public Array{
public:
    StringArray();
    StringArray(const std::string& arrayString);
    StringArray(const StringArray& copyArray);
    ~StringArray();
    bool initWithString(const std::string& arrayString);
    std::string serialize();
    int size();
    void clear();
    std::string& operator[](int idx);
    StringArray& operator=(const StringArray&);
    StringArray& append(std::string item);
private:
    std::vector<std::string> m_array;
};
/**
 *  \file   BaseType.h   
 *  \class  TupleItem
 *  \brief  元组元素	
 */
 
class TupleItem{
public:
    TupleItem(int);
    TupleItem(double);
    TupleItem(std::string);
    TupleItem(const TupleItem&);
    virtual ~TupleItem();
    int baseType();
    int toInt();
    double toDouble();
    std::string toString();
private:
    int m_type;
    double m_value;
    std::string m_string;
};

/**
 *  \file   BaseType.h   
 *  \class  Tuple
 *  \brief  元组	
 */
class Tuple:public Array{
public:
    Tuple();
    Tuple(const Tuple&);
    virtual ~Tuple();
    bool initWithString(const std::string& tupleString);
    int size();
    int type();
    void clear();
    std::string serialize();
    Tuple& append(int item);
    Tuple& append(double item);
    Tuple& append(const std::string& item);
    Tuple& append(TupleItem& item);
    Tuple& insert(int idx, int item);
    Tuple& insert(int idx, double item);
    Tuple& insert(int idx, const std::string& item);
    Tuple& insert(int idx, TupleItem& item);
    TupleItem& operator[](int idx);
    Tuple& operator=(const Tuple&);
    friend std::ostream& operator<<(std::ostream&,Tuple&);
private:
    std::vector<TupleItem*> m_valueVect;
};
}
#endif
